#include "StdAfx.h"
#include "Camera.h"
void Camera::setFOV(Vector3& position, Vector3& up, Vector3& target, GLfloat fovy, GLfloat aspect, GLfloat nearPlane, GLfloat farPlane)
{
	this->target_local = Vector3(0, 0, -(position - target).Length());
	this->up = up;
	projectionMatrix.SetPerspective(fovy, aspect, nearPlane, farPlane);
	translationMatrix.SetIdentity();
	rotationMatrix.SetIdentity();
	displace = position;
	xaxis = Vector3(1, 0, 0);
	yaxis = Vector3(0, 1, 0);
	zaxis = Vector3(0, 0, 1);
	calcMatrix();
}

void Camera::calcAxis(Vector3& position, Vector3& target)
{
	zaxis = (position - target).Normalize();
	xaxis = (up.Cross(zaxis)).Normalize();
	yaxis = zaxis.Cross(xaxis).Normalize();
}


Matrix Camera::getViewMatrix()
{
	// View matrix
	position = getPosition();
	Vector3 target = getTarget();
  	calcAxis(position, target);

	Matrix* v = &viewMatrix;
	v->m[0][0]=xaxis.x;				v->m[1][0]=yaxis.x;				v->m[2][0]=zaxis.x;				v->m[3][0]=0;
	v->m[0][1]=xaxis.y;				v->m[1][1]=yaxis.y;				v->m[2][1]=zaxis.y;				v->m[3][1]=0;
	v->m[0][2]=xaxis.z;				v->m[1][2]=yaxis.z;				v->m[2][2]=zaxis.z;				v->m[3][2]=0;
	v->m[0][3]=-position.Dot(xaxis);v->m[1][3]=-position.Dot(yaxis);v->m[2][3]=-position.Dot(zaxis);v->m[3][3]=1;
	//
	return viewMatrix.Transpose();
}
Matrix& Camera::getProjectionMatrix()
{
	return projectionMatrix;
}

Vector3 Camera::getPosition()
{
	//calcMatrix();
	Vector3 position;
	position = Vector4(0, 0, 0, 1) * translationMatrix;
	return position;
}


Vector3 Camera::getTarget()
{
	Vector3 target;
	target =  Vector4(target_local, 1) * rotationMatrix * translationMatrix;
	//esLogMessage("Target: x=%f; y=%f; z=%f;\n", target.x,s target.y, target.z);
	return target;
}

void Camera::calcMatrix()
{
	Matrix tx, ty, tz, rx, ry, rz;
	tx.SetTranslation(xaxis * displace.x);
	ty.SetTranslation(yaxis * displace.y);
	tz.SetTranslation(zaxis * displace.z);
	rx.SetRotationX(rotate.x);
	ry.SetRotationY(rotate.y);
	rz.SetRotationZ(rotate.z);
	rotationMatrix = rotationMatrix * rz * rx * ry;
	translationMatrix = translationMatrix * tx * ty * tz;

	displace = Vector3(0, 0, 0);
	rotate = Vector3(0, 0, 0);
}

void Camera::moveLeft()
{
	displace.x+=-TRANSLATE_STEP;
	calcMatrix();
	
}
void Camera::moveRight()
{
	displace.x+=TRANSLATE_STEP;
	calcMatrix();
	
}
void Camera::moveForward()
{
	displace.z-=TRANSLATE_STEP;
	calcMatrix();
	
}
void Camera::moveBackward()
{
	displace.z+=TRANSLATE_STEP;
	calcMatrix();
	
}

void Camera::RotateLeft()
{
	rotate.y += ROTATE_STEP;
	calcMatrix();

}
void Camera::RotateRight()
{
	rotate.y += -ROTATE_STEP;
	calcMatrix();

}
void Camera::RotateUp()
{ 
	rotate.x += ROTATE_STEP;
	calcMatrix();

}
void Camera::RotateDown()
{
	rotate.x += -ROTATE_STEP;
	calcMatrix();

}

Camera::Camera(void)
{
}

Camera::~Camera(void)
{
}